class Message{
    constructor(){

    }

    static get_normal_msg(){
        let m_normal_obj = {
            tabId: chrome.devtools.inspectedWindow.tabId,
            msg_type: MSG_NORMAL,
        }

        return m_normal_obj;
    }

    static msg_send_to_background(msg){
        cbf_msg_send_to_background(msg);
    }
}


class ElementList{

    /*
        Array
    */
    constructor(){
        /*
            :param tree_space:  [Array] - [Object] - {left:'int', node_value:'int', right:'int', parent:'int', prev_brother:'int'}

            :param node_space:  
            [Array] - [Object] - {
                tag_name:'str',
                attr_list:'Array'-[Object]{name, value, is_selected},
                text:'str',
                is_text_selected: 'bollean',
                is_selected:'bollean'
            }
        */
        this.tree_space = null;
        this.node_space = null;
    }

    init_list(cross_list_space, cross_node_space){
        /*
            初始化列表
            :param cross_list_space:    类型: [Array] 元素： [Object] - {left:'int', node_value:'int', right:'int'}
            :param cross_node_space:    类型: [Array] 元素： [Object] - {tag_name:'str', attr_x:'Object'{name, value}, attr_length:'int', text:'str'}
        */

        // 整理 node_list
        let new_node_list = new Array();
        for (let i = 0; i < cross_node_space.length; i++) {
            let node = cross_node_space[i];
            let new_node_obj = new Object();
            new_node_obj.tag_name = node.tag_name;
            new_node_obj.text = node.text;
            new_node_obj.is_text_selected = false;
            new_node_obj.attr_list = new Array();
            new_node_obj.is_selected = false;
            
            
            for (let j = 0; j < node.attr_length; j++) {
                let attr_reference_name = "attr_" + j;
                let new_attr_obj = new Object();
                new_attr_obj.is_selected = false;
                new_attr_obj.name = node[attr_reference_name].name;
                new_attr_obj.value = node[attr_reference_name].value;
                new_node_obj.attr_list.push(new_attr_obj);
            }

            new_node_list.push(new_node_obj);
            
        }

        this.tree_space = cross_list_space;
        this.node_space = new_node_list;
        this.init_tree_space();
        console.log("Tree:");
        console.log(this.tree_space);
        console.log(this.node_space);
        
    }

    init_tree_space(){
        this.iterate_init_tree_sapce(0, -1, -1);
    }

    iterate_init_tree_sapce(node_index, parent_index, prev_brother){
        let tree_node = this.get_tree_node(node_index);
        tree_node.parent = parent_index;
        tree_node.prev_brother = prev_brother;

        if (tree_node.left !== -1){
            this.iterate_init_tree_sapce(tree_node.left, node_index, -1)
        }

        if (tree_node.right !== -1){
            this.iterate_init_tree_sapce(tree_node.right, parent_index, node_index);
        }
    }

    clear_list(){
        this.tree_space = null;
        this.node_list = null;
    }

    // node space
    // 设置节点选中的属性
    set_attr_selected(node_id, attr_id){
        if (attr_id === '-1'){
            this.node_space[node_id].is_text_selected = true;
        }else{
            this.node_space[node_id].attr_list[attr_id].is_selected = true;
        }

        // this.node_space[node_id].is_selected = true;
        this.set_node_selected(node_id);
    }

    // 取消节点的选中属性
    cancel_attr_selected(node_id, attr_id){
        if (attr_id === '-1'){
            this.node_space[node_id].is_text_selected = false;
        }else{
            this.node_space[node_id].attr_list[attr_id].is_selected = false;
        }

        for (let i = 0; i < this.node_space[node_id].attr_list.length; i++) {
            const attr = this.node_space[node_id].attr_list[i];
            if (attr.is_selected === true){
                // this.node_space[node_id].is_selected = true;
                this.set_node_selected(node_id);
                return true;
            }
        }

        // this.node_space[node_id].is_selected = false;
        this.cancel_node_selected(node_id);
        return true;
    }

    // 设置节点为选中状态
    set_node_selected(node_id){
        this.node_space[node_id].is_selected = true;
    }

    // 设置节点为未选中状态
    cancel_node_selected(node_id){
        this.node_space[node_id].is_selected = false;
    }

    // 重置节点的选中状态
    reset_node_selected(node_id){

        for (let i = -1; i < this.node_space[node_id].attr_list.length; i++) {
            this.cancel_attr_selected(node_id, i);
        }
    }

    // 以列表的形式返回已选中的节点
    get_selected_node_list(){
        /*
            :return: liet - [object]
            [
                node_id:    Int
                node_obj:   node_space[x]
            ]
        */
        let new_list = new Array();
        for (let i = 0; i < this.node_space.length; i++) {
            const node = this.node_space[i];
            if (node.is_selected === true){
                let element = new Object();
                element.node_obj = node;
                element.node_id = i;
                new_list.push(element);
            }
            
        }
        return new_list;
    }

    // 从tree_space里面获取值为node_index的节点
    get_tree_node(node_index){
        for (let i = 0; i < this.tree_space.length; i++) {
            const tree_node = this.tree_space[i];
            if (tree_node.node_value === node_index){
                return tree_node;
            }
        }

        return false;
    }

    // 返回node_index所有兄弟节点（node_space）
    get_brother_node_list(node_index){
        let tree_node = this.get_tree_node(node_index);
        let brother_node_list = new Array();
        while(tree_node.right !== -1){
            brother_node_list.append(this.node_space[tree_node.right]);
            tree_node = this.get_tree_node(tree_node.right);
        }

        return brother_node_list;
    }

    // 以xpath的形式返回选中的对象
    get_selected_node_list_in_xpath(){
        let result_obj = new Array;
        let tmp_array = new Array;
        result_obj = this.iterate_generate_selected_node_xpath(0, '', tmp_array);
        return result_obj;
    }

    iterate_generate_selected_node_xpath(node_index, xpath, result_obj){
        /*
            :param node_index:      int
            :param xpath:           string
            :param result_obj:      object
        */

       
        let tree_obj = this.get_tree_node(node_index);
        let node_obj = this.node_space[node_index];

        // 生成xpath
        let tmp_tree_obj = tree_obj;
        let counter = 1;
        let has_prev = false;
        let has_next = false;
        while(tmp_tree_obj.prev_brother !== -1){
            const node_obj_prev_brother = this.node_space[tmp_tree_obj.prev_brother];
            if (node_obj_prev_brother.tag_name === node_obj.tag_name){
                counter++;
                has_prev = true;
            }
            tmp_tree_obj = this.get_tree_node(tmp_tree_obj.prev_brother);
        }

        if (has_prev === true){
            // xpath = xpath + "/" + node_obj.tag_name.toLowerCase() + "["+ counter +"]";
        }else{
            tmp_tree_obj = tree_obj;
            // let has_next = false;
            while(tmp_tree_obj.right !== -1){
                const node_obj_next_brother = this.node_space[tmp_tree_obj.right];
                if (node_obj_next_brother.tag_name === node_obj.tag_name){
                    has_next = true;
                    break;
                }else{
                    tmp_tree_obj = this.get_tree_node(tmp_tree_obj.right);
                }

            }

            // if (has_next === true){
            //     xpath = xpath + "/" + node_obj.tag_name.toLowerCase() + "[1]";
            // }else{
            //     xpath = xpath + "/" + node_obj.tag_name.toLowerCase();
            // }
        }
        
        if (node_obj.is_selected === true){

            let tmp_xpath = "";
            if (has_prev === true){
                tmp_xpath = xpath + "/" + node_obj.tag_name.toLowerCase() + "["+ counter +"]";
            }else if(has_next === true){
                tmp_xpath = xpath + "/" + node_obj.tag_name.toLowerCase() + "[1]";
            }else{
                tmp_xpath = xpath + "/" + node_obj.tag_name.toLowerCase();
            }

            // 添加元素
            let new_obj = new Object();
            new_obj.xpath = tmp_xpath;
            new_obj.selected_attr_list = new Array();
            
            for (let j = 0; j < node_obj.attr_list.length; j++) {
                const attr = node_obj.attr_list[j];
                if (attr.is_selected === true){
                    new_obj.selected_attr_list.push(attr);
                }
            }

            if (node_obj.is_text_selected === true){
                let text_obj = new Object();
                text_obj.name = "mc_text";
                text_obj.value = node_obj.text
                new_obj.selected_attr_list.push(text_obj);
            }


            result_obj.push(new_obj);
        }

        
        if (tree_obj.left !== -1){
            let tmp_xpath = "";
            if (has_prev === true){
                tmp_xpath = xpath + "/" + node_obj.tag_name.toLowerCase() + "["+ counter +"]";
            }else if(has_next === true){
                tmp_xpath = xpath + "/" + node_obj.tag_name.toLowerCase() + "[1]";
            }else{
                tmp_xpath = xpath + "/" + node_obj.tag_name.toLowerCase();
            }
            result_obj = this.iterate_generate_selected_node_xpath(tree_obj.left, tmp_xpath, result_obj);
        }else if(tree_obj.right !== -1){
            result_obj = this.iterate_generate_selected_node_xpath(tree_obj.right, xpath, result_obj);
        }

        return result_obj;

    }
    
    
}


class ElementCollector{
    constructor(analyzer){
        this.hobjg_collector = $("#div_collector");
        this.analyzer = analyzer;
        // this.element_list = analyzer.element_list;
        // this.update_owner();
    }

    init(){
        this.hobjg_collector.empty();
        this.analyzer.element_list.clear_list();
    }

    register(){
        // this.update_owner();
    }

    // update_owner(){
    //     this.analyzer = this.get_html_analyzer();
    //     this.element_list = this.analyzer.element_list;
    // }

    get_html_analyzer(){
        return HtmlAnalyzer.getInstance();
    }

    refresh(){
        /*
            更新collector视图
        */

        let div_collector = $("#div_collector");
        div_collector.empty();
        let selected_node_list = this.analyzer.element_list.get_selected_node_list();
        for (let i = 0; i < selected_node_list.length; i++) {
            const node = selected_node_list[i].node_obj;
            const node_id = selected_node_list[i].node_id;
            let node_html_element = this.generate_selected_node(node_id, node);
            div_collector.append(node_html_element);
        }
    }

    generate_selected_node(node_id, node){
        /*
            生成collector显示的单个节点的html

            <div class="row">
                <div class="col-md-12 col-sm-12">
                    <span>[p]</span><span>[delete]</span>
                </div>
            </div>

            :param node_id: Int
            :param node:    element_list.node_space[x]

            [Object] - {
                tag_name:'str',
                attr_list:'Array'-[Object]{name, value, is_selected},
                text:'str',
                is_text_selected: 'bollean',
                is_selected:'bollean'
            }
        */

        let div_row = $("<div class='row'></div>");
        let div_col = $("<div class='col-md-12 col-sm-12 collector_element' name='collector_element' ce_node_id='"+ node_id +"'></div>")
        let span_node_tag_name = $("<span></span>");
        let span_node_delete_tag = $("<span tag_id='"+ node_id +"'>[delete]</span>");

        span_node_tag_name.append("["+ node.tag_name +"]");
        div_col.append(span_node_tag_name);
        div_col.append(span_node_delete_tag);
        div_row.append(div_col);
        
        return div_row;
    }

    reset_all_tag_background_color(){
        $(".collector_element").css("background-color", "");
    }

    set_tag_background_color(jq_target){
        if (jq_target.attr("name") !== "collector_element"){
            return -1;
        }else{
            jq_target.css("background", "#D38A4F");
        }
    }



}


class ElementSelector{
    
    constructor(analyzer){
        this.analyzer = analyzer;
        // this.element_list = analyzer.element_list;
        this.hobj_selector_tag_name = $("#selector_tag_name");
        this.hobj_selector_attr_list = $("#selector_attrs");
    }

    init(){
        this.hobj_selector_attr_list.empty();
        this.hobj_selector_tag_name.empty();
    }
    
    register(){
        // this.update_owner();

    }

    // update_owner(){
    //     this.analyzer = this.get_html_analyzer();
    //     this.element_list = this.analyzer.element_list;
    // }

    get_html_analyzer(){
        return HtmlAnalyzer.getInstance();
    }

    set_tag_detail(jq_target){
        /*
            在selector中显示tag的详细信息
        */


        if (jq_target.attr("name") === "div_col_tag_name_up"){
            let tag_id = jq_target.attr("tag_id")
            let tag = this.analyzer.element_list.node_space[tag_id];
            console.log(tag);

            // 设置标签名称
            $("#selector_tag_name").text(tag.tag_name);

            // 设置标签属性
            let div_attrs = $("#selector_attrs");
            for (let i = 0; i < tag.attr_list.length; i++) {
                let attr = tag.attr_list[i];
                let jq_attr = this.generate_attr(tag_id, i, attr);
                if (attr.is_selected === true){
                    jq_attr.find("input").prop("checked", true);
                }
                div_attrs.append(jq_attr);
            }

            if (tag.text !== ''){
                let jq_text_attr = this.generate_attr_text(tag_id, tag.text);
                if (tag.is_text_selected === true){
                    jq_text_attr.find("input").prop('checked', true);
                }
                
                div_attrs.append(jq_text_attr);
            }
        }

    }

    reset_tag_detail(){
        /*
            重置selector的html显示
        */
       let div_tag_name = $("#selector_tag_name");
       let div_attrs = $("#selector_attrs");
       div_attrs.empty();
       div_tag_name.empty();
    }

    generate_attr(node_id, attr_id, attr){
        /*
            构造单个attr html元素
            :param i:       [Int]attr的下标
            :param attr:    [Object] {name, value}
            :return:        jQuery
        */

        let div_col = $("<div class='col-md-12 col-sm-12'></div>");
        let attr_check_box = $("<input class='form-check-input' type='checkbox' id='attrs_"+ attr_id +"' attr_id="+ attr_id +" node_id="+ node_id +">");
        let attr_name = $("<label class='form-check-label' for='attrs_"+ attr_id +"'>"+ attr.name +"</label>");
        let attr_value_collapse = $("<label data-toggle='collapse' href='#attr_"+ attr_id +"_values' aria-expanded='false'>▲</label>");

        let div_attr_values = $("<div class='collapse show' id='attr_"+ attr_id +"_values'></div>");
        let p_values = $("<p class='text-truncate'></p>");
        p_values.append(attr.value);
        div_attr_values.append(p_values);

        div_col.append(attr_check_box);
        div_col.append(attr_name);
        div_col.append(attr_value_collapse);
        div_col.append(div_attr_values);

        return div_col;
    }

    generate_attr_text(node_id, text){
        let div_col = $("<div class='col-md-12 col-sm-12'></div>");
        let attr_check_box = $("<input class='form-check-input' type='checkbox' id='attrs_text' attr_id="+ -1 +" node_id="+ node_id +">");
        let attr_name = $("<label class='form-check-label' for='attrs_text'>文本内容</label>");
        let attr_value_collapse = $("<label data-toggle='collapse' href='#attr_text_values' aria-expanded='false'>▲</label>");

        let div_attr_values = $("<div class='collapse show' id='attr_text_values'></div>");
        let p_values = $("<p class='text-truncate'></p>");
        p_values.append(text);
        div_attr_values.append(p_values);

        div_col.append(attr_check_box);
        div_col.append(attr_name);
        div_col.append(attr_value_collapse);
        div_col.append(div_attr_values);

        return div_col;
    }

}


class ElementsViewer{

    constructor(analyzer){
        this.analyzer = analyzer;
        // this.element_list = analyzer.element_list;
        this.hobj_viewer = $("#div_viewer");

        this.normal_msg = {

        }
        
    }

    // 注册html事件
    register(){
        // this.update_owner();
    }

    // 显示html元素
    active(){

    }

    // 初始化viewer
    init(){
        this.hobj_viewer.empty();
    }

    // update_owner(){
    //     this.analyzer = this.get_html_analyzer();
    //     this.element_list = this.analyzer.element_list;
    // }

    get_html_analyzer(){
        return HtmlAnalyzer.getInstance();
    }

    // 构造html元素
    generate_viewer(){
        /*
            构造html元素
        */
       
        // this.update_owner();
        console.log("==ElementsViewer.generate_viewer==");
        console.log("tree space:");
        console.log(this.analyzer.element_list.tree_space);
        console.log("node space");
        console.log(this.analyzer.element_list.node_space);
        

        let div_viewer = $("#div_viewer");
        let node_id = 0;
        let root_node_obj = this.analyzer.element_list.tree_space[node_id];
        let root_jq_obj = this.create_single_node_html_source(node_id);

        let jq_content = this.iterate_generate_all_html_source(root_jq_obj, root_node_obj, node_id);

        root_jq_obj.append(jq_content);
        div_viewer.append(root_jq_obj);
    }

    create_single_node_html_source(tag_id){
        /*
            构造单个节点的html
            :param tag_id:      tag的下标
            return:             jQuery
        */

        if (this.analyzer === null || this.analyzer === undefined){
            console.log("==ElementViewer==");
            console.log("Error: analyzer init error");
            return false;
        }

        let node = this.analyzer.element_list.node_space[tag_id];

        let span_left_braces = $("<span style='color:#2C4546'>&lt;</span>");                  // <
        let span_right_braces = $("<span style='color:#2C4546'>&gt;</span>");                 // >
        let span_tilt = $("<span style='color:#2C4546'>/</span>");                            // /
        let span_tag_name = $("<span class='text-lowercase' style='color:#C16BB8'>" + node.tag_name + "</span>");    // tag_name
        let span_space = $("<span>&nbsp;</span>")

        let div_container = $("<div class='container ml-4' id='"+ tag_id +"_tag'></div>");
        
        let div_tag_name_up_container = $("<div class='row' name='tag_name_up'></div>");
        let div_tag_name_content_container = $("<div class='row collapse show' id='"+ tag_id +"_tag_content'></div>");
        let div_tag_name_down_container = $("<div class='row' name='tag_name_down'></div>");


        // 构造上标签
        let col_tag_name_up = $("<div class='col-md-12 col-sm-12 align-self-center div_col_tag_name_up' name='div_col_tag_name_up' tag_id="+ tag_id +" ve_node_id="+ tag_id +"></div>");
        let img_tag_name_up = $("<img src='icons/down_16.png' data-toggle='collapse' href='#"+ tag_id +"_tag_content' class='d-inline-flex' aria-expanded='true' aria-controls='row_testss'>")

        let p_tag = $("<span name='span_tag_up_name'></span>");
        let span_attrs = $("<span name='span_attrs'></span>");
        for (let i = 0; i < this.analyzer.element_list.node_space[tag_id].attr_list.length; i++) {
            let attr = this.analyzer.element_list.node_space[tag_id].attr_list[i];

            let span_attr_name = $("<span name='attr_name' style='color:#64B92C'></span>");
            let span_attr_value = $("<span name='attr_value' style='max-width: 500px;' class='d-inline-block text-truncate'></span>");
            let span_operation = $("<span>=</span>");
            if (attr.value === null || attr.value === ''){
                // str_attr = attr.name;
                span_attr_name.append(attr.name);
                span_attrs.append(span_attr_name);
            }else{
                span_attr_name.append(attr.name);
                // span_attr_value.append(attr.value);
                span_attr_value.append("...");
                // str_attr = attr.name + "='" + attr.value + "'"
                span_attrs.append(span_attr_name);
                span_attrs.append(span_operation);
                span_attrs.append(span_attr_value);
                span_attrs.append(span_space.clone());
            }
            
            
        }

        p_tag.append(span_left_braces.clone());
        p_tag.append(span_tag_name.clone());
        p_tag.append(span_space.clone());
        p_tag.append(span_attrs);
        p_tag.append(span_right_braces.clone());

        // 插入上标签
        col_tag_name_up.append(img_tag_name_up);
        col_tag_name_up.append(p_tag);
        div_tag_name_up_container.append(col_tag_name_up);

        // 构造下标签
        let col_tag_name_down = $("<div class='col'></div>");
        let p_tag_end = $("<span></span>");

        p_tag_end.append(span_left_braces.clone());
        p_tag_end.append(span_tilt.clone());
        p_tag_end.append(span_tag_name.clone());
        p_tag_end.append(span_right_braces.clone());
        // p_tag_end.append("&lt; "+ "/" + node.tag_name +" &gt;");
        col_tag_name_down.append(p_tag_end);

        // 插入下标签
        div_tag_name_down_container.append(col_tag_name_down);


        // 插入标签文本内容
        if (node.text !== ''){
            let div_tag_content = $("<div class='col'></div>")
            let p_tag_content = $("<span></span>");
            p_tag_content.append(node.text);
            div_tag_content.append(p_tag_content);
            div_tag_name_content_container.append(div_tag_content);
        }

        div_container.append(div_tag_name_up_container);
        div_container.append(div_tag_name_content_container);
        div_container.append(div_tag_name_down_container);

        return div_container;
    }


    iterate_generate_all_html_source(root_jq_obj, root_node_obj, node_id){
        /*
            :param root_jq_obj:     已生成的html源码的当前root jquery对象
            :param root_node_obj:   root_jq_obj tree_sapce列表的对象
            :param node_id:         root_node_obj在node_space中的下标
        */
       
        let jq_root_content = root_jq_obj.children("div#"+ node_id +"_tag_content");

        if (root_node_obj.left !== -1){

            let next_root_jq_obj = this.create_single_node_html_source(root_node_obj.left);
            let next_node_id = root_node_obj.left;
            let next_root_node_obj = null;
            for (let j = 0; j < this.analyzer.element_list.tree_space.length; j++) {
                if (this.analyzer.element_list.tree_space[j].node_value === next_node_id){
                    next_root_node_obj = this.analyzer.element_list.tree_space[j];
                    break;
                }
            }

            // 插入html内容
            // jq_root_content.append(next_root_jq_obj);

            // 进入下一次迭代
            // 返回左子树迭代的结果(所有)
            // 迭代返回加工后的next_root_jq_obj
            let left_result = this.iterate_generate_all_html_source(next_root_jq_obj, next_root_node_obj, next_node_id);
            // jq_root_content = this.iterate_generate_all_html_source(next_root_jq_obj, next_root_node_obj, next_node_id);
            jq_root_content.append(left_result);

            
            // 统计兄弟数量
            let next_right = next_root_node_obj.right;
            while(next_right !== -1){
                next_node_id = next_root_node_obj.right;
                // next_root_node_obj = this.element_list.node_space[next_root_node_obj.right];
                next_root_jq_obj = this.create_single_node_html_source(next_node_id);
                // jq_root_content.append(next_root_jq_obj);
                for (let j = 0; j < this.analyzer.element_list.tree_space.length; j++) {
                    if (this.analyzer.element_list.tree_space[j].node_value === next_node_id){
                        next_root_node_obj = this.analyzer.element_list.tree_space[j];
                        break;
                    }
                }
                // let right_result = this.iterate_generate_all_html_source(root_jq_obj, next_root_node_obj, next_node_id); 
                let right_result = this.iterate_generate_all_html_source(next_root_jq_obj, next_root_node_obj, next_node_id); 
                // jq_root_content = this.iterate_generate_all_html_source(root_jq_obj, next_root_node_obj, next_node_id);
                jq_root_content.append(right_result);
                next_right = next_root_node_obj.right;                
            }
            
        }

        return root_jq_obj;

    }


    /*
        元素表现
    */
    set_tag_background_color(jq_target){
        /*
            设置标签名的背景颜色
        */
        if (jq_target.attr("name") === "div_col_tag_name_up"){
            jq_target.css("background-color", "blueviolet");
        }
    }

    reset_all_tag_background_color(){
        // 重置所有标签名的背景颜色
        $(".div_col_tag_name_up").css("background-color", "");
    }


    /*
        发送消息
    */

    m_refresh_viewer(data_binding_xpath){
        let msg = Message.get_normal_msg();
        msg.todo = "refresh_viewer";
        msg.xpath = data_binding_xpath;
        Message.msg_send_to_background(msg);
    }

}

class HtmlAnalyzer{
    
    constructor(){
        // 所有节点的列表
        this.element_list = new ElementList();     
        this.obj_ElementsViewer = new ElementsViewer(this);
        this.obj_ElementSelector = new ElementSelector(this);
        this.obj_ElementCollector = new ElementCollector(this);
    }

    static getInstance(){
        return this._instance || (this._instance = new HtmlAnalyzer());
    }

    // 注册html组建
    register(){
        this.obj_ElementCollector.register();
        this.obj_ElementSelector.register();
        this.obj_ElementsViewer.register();

        // 事件委托
        let mc_this = this;
        $("#div_viewer").click(function(e){
            /*
                点击标签
            */
            console.log("viewer clicked");
            let jq_target = $(e.target);

            // 设置viewer
            mc_this.obj_ElementsViewer.reset_all_tag_background_color();
            mc_this.obj_ElementsViewer.set_tag_background_color(jq_target);

            // 设置selector
            mc_this.obj_ElementSelector.reset_tag_detail();
            mc_this.obj_ElementSelector.set_tag_detail(jq_target);
            // if (jq_target.attr("name") === "div_col_tag_name_up"){
            //     let node_id = jq_target.attr("tag_id");
            //     mc_this.obj_ElementSelector.show_tag_detail(node_id);
            // }
            
        });

        // 捕获属性的点击
        $("#selector_attrs").click(function(e){
            let jq_target = $(e.target);
            if (jq_target.attr("type") === "checkbox"){
                let node_id = jq_target.attr("node_id");
                let attr_id = jq_target.attr("attr_id");
                if (jq_target.prop("checked") === true){
                    mc_this.element_list.set_attr_selected(node_id, attr_id);
                }else if(jq_target.prop("checked") === false){
                    mc_this.element_list.cancel_attr_selected(node_id, attr_id);
                }

                // 更新collector
                mc_this.obj_ElementCollector.refresh();
            }
        });

        // collector事件委托
        $("#div_collector").click(function(e){
            let jq_target = $(e.target);
            if (jq_target.attr("name") === "collector_element"){
                // 触发点击动作
                let node_id = jq_target.attr("ce_node_id");
                $("div[ve_node_id="+ node_id +"]").click();

                // 刷新背景
                mc_this.obj_ElementCollector.reset_all_tag_background_color();
                mc_this.obj_ElementCollector.set_tag_background_color(jq_target);
            }

        });

        // 全局事件委托
        $("#container_get_data_structure").click(function(e){
            let jq_target = $(e.target);
            if (jq_target.attr("name") !== "collector_element" && jq_target.attr("type") !== "checkbox"){
                mc_this.obj_ElementCollector.reset_all_tag_background_color();
            }
        });
    }

    // 显示html组建
    active(){

    }

    // 初始html元素内容以及缓存内容
    init_analyzer(cross_list_space, cross_node_space){
        /*
            初始html元素内容以及缓存内容
            :param cross_list_space:    类型: [Array] 元素： [Object] - {left:'int', node_value:'int', right:'int'}
            :param cross_node_space:    类型: [Array] 元素： [Object] - {tag_name:'str', attr_x:'Object'{name, value}, attr_length:'int'}
            :return:

            node_space[0], list_space[0]是根节点
        */

        // 初始哈viewer， selector， collector
        this.obj_ElementsViewer.init();
        this.obj_ElementSelector.init();
        this.obj_ElementCollector.init();

        // 生成列表
        this.element_list.init_list(cross_list_space, cross_node_space);

        // 生成html元素
        this.obj_ElementsViewer.generate_viewer();
    }
}


class GetDataStructure{
    constructor(){
        this.data_binding_set = new DataBinding();                      // 数据标定
        this.html_analyzer = HtmlAnalyzer.getInstance();

        this.hobj_btn_viewer_refresh = $("#btn_viewer_refresh");
    }

    register_GetDataStructure(){

        let mc_this = this;

        this.data_binding_set.register();
        this.html_analyzer.register();


        this.hobj_btn_viewer_refresh.click(function(){
            /*
                刷新viewer
            */

            if (mc_this.data_binding_set.is_data_binding_done() === false){
                return;
            }else{
                mc_this.html_analyzer.obj_ElementsViewer.m_refresh_viewer(mc_this.data_binding_set.xpath_binding);
            }
        });
    }

    active_GetDataStructure(){
        this.data_binding_set.active();
    }

    return_submit_obj(){

        let return_obj = new Object();

        if (this.data_binding_set.is_data_binding_done() === true){
            // 数据标定信息
            return_obj.data_binding_main = this.data_binding_set.xpath_binding;
            return_obj.data_binding_max = this.data_binding_set.max_xpath_binding;
            return_obj.data_binding_sub_list = this.data_binding_set.sub_xpath_binding_list_to_obj();
            return_obj.data_binding_sub_list_length = this.data_binding_set.sub_xpath_binding_list.length;

            // 结构信息
            return_obj.structure = this.html_analyzer.element_list.get_selected_node_list_in_xpath();
            return_obj.structure_length = return_obj.structure.length;

            for (let i = 0; i < return_obj.structure.length; i++) {
                let selected_node = return_obj.structure[i];
                selected_node.selected_attr_list_length = selected_node.selected_attr_list.length;
            }
            
            return return_obj;
        }else {
            return false;
        }
    }
}